<script lang="ts" setup>
import { apiUser } from "@/api/sys";
import { useMessage } from "@/hooks/web/use-message";
import { AdvancedFilter, Comparator, UserStatus, type AdvancedSearch, type PageInfo, type UserInfo } from "@/models";
import { generateAuditColumns } from "@/utils";
import { computed, onMounted, reactive, ref } from "vue";
import { type VxeGridInstance, type VxeGridProps } from "vxe-table";
import Delete from "~icons/ep/delete";
import Edit from "~icons/ep/edit";
import Plus from "~icons/ep/plus";
import Search from "~icons/ep/search";
import editUserVue from "./edit-user.vue";

//#region [state]
const keyword = ref<string>();
const hasChecked = computed(() => !!gridRef.value?.getCheckboxRecords().length);
const { confirmDelete } = useMessage();
const { LIKE } = Comparator;
//#endregion

//#region [grid]
const gridRef = ref<VxeGridInstance>();
const gridPager = ref<PageInfo>({ currentPage: 1, pageSize: 20, total: 0 });
const gridProps = reactive<VxeGridProps<UserInfo>>({
  autoResize: true,
  size: "small",
  border: "full",
  showOverflow: "ellipsis",
  columnConfig: { resizable: true, minWidth: 60 },
  rowConfig: { keyField: "id" },
  toolbarConfig: { slots: { buttons: "toolbar_buttons" } },
  pagerConfig: gridPager.value,
  columns: [
    { type: "checkbox", width: 60, align: "center" },
    { field: "uid", title: "账号" },
    { field: "name", title: "名称" },
    { field: "email", title: "邮箱" },
    { field: "currentRoleName", title: "当前角色" },
    { field: "loginTimes", title: "登录次数" },
    { field: "status", title: "状态", formatter: ({ cellValue }) => UserStatus[cellValue] },
    ...generateAuditColumns<UserInfo>({ dateMode: "date" }),
    { title: "操作", width: 120, align: "center", fixed: "right", slots: { default: "field_ops" } },
  ],
});
//#endregion

//#region [form]
const editRef = ref<InstanceType<typeof editUserVue>>();
//#endregion

//#region [action]
async function load() {
  gridProps.loading = true;

  let search: AdvancedSearch<UserInfo> = undefined;
  if (keyword.value) {
    search = { f: new AdvancedFilter<UserInfo>({ name: { value: keyword.value, comparator: LIKE }, uid: { value: keyword.value, comparator: LIKE } }, "OR") };
  }

  const response = await apiUser.page<UserInfo>(search, gridPager.value);
  if (response.value) {
    gridProps.data = response.value.data || [];
    gridPager.value = response.value.pageInfo;
  }

  gridRef.value?.clearCheckboxRow();
  gridProps.loading = false;
}

function handleAdd() {
  editRef.value?.open();
}
function handleEdit(user: UserInfo) {
  editRef.value?.open(user);
}
function handleDel(user: UserInfo) {
  confirmDelete(
    `是否删除用户【${user.name}(${user.uid})】的所有资料？`,
    async () => {
      await apiUser.remove(user.id);
      await load();
    },
    { title: "删除用户确认" },
  );
}
function handleDelBatch() {
  const users = gridRef.value?.getCheckboxRecords();
  confirmDelete(
    `是否删除勾选用户（共${users!.length}条）的所有资料？`,
    async () => {
      await apiUser.removeAll(users!.map((u) => u.id));
      await load();
    },
    { title: "删除用户确认" },
  );
}
//#endregion

onMounted(() => {
  load();
});
</script>

<template>
  <div class="m-3">
    <el-form :inline="true">
      <el-form-item class="w-md">
        <el-input v-model="keyword" placeholder="请输入名称或账号" clearable @keyup.enter="load" />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" :icon="Search" plain @click="load">搜索</el-button>
      </el-form-item>
    </el-form>

    <vxe-grid ref="gridRef" :="gridProps">
      <template #toolbar_buttons>
        <el-button type="primary" :icon="Plus" plain title="添加用户" @click="handleAdd">新增</el-button>
        <el-button type="danger" :icon="Delete" plain title="批量删除用户" :disabled="!hasChecked" @click="handleDelBatch">删除</el-button>
      </template>
      <template #field_ops="{ row }">
        <el-button size="small" type="warning" :icon="Edit" title="编辑" @click="handleEdit(row)"></el-button>
        <el-button size="small" type="danger" :icon="Delete" title="删除" @click="handleDel(row)"></el-button>
      </template>
    </vxe-grid>
  </div>

  <edit-user-vue ref="editRef" @onsaved="load" />
</template>

<style lang="scss" scoped>
.el-button--small {
  padding: 5px;
}
</style>
